package com.dahua.messagesyncsh.business.mitsubishi.service.impl;

import com.dahua.messagesyncsh.business.mitsubishi.common.constant.EventTypeEnum;
import com.dahua.messagesyncsh.business.mitsubishi.common.util.GsonUtils;
import com.dahua.messagesyncsh.business.mitsubishi.pojo.dto.DecryptDto;
import com.dahua.messagesyncsh.business.mitsubishi.pojo.vo.PushResponseVo;
import com.dahua.messagesyncsh.business.mitsubishi.service.PushAgentService;
import com.dahua.messagesyncsh.criteria.EquipmentQueryCriteria;
import com.dahua.messagesyncsh.entity.Equipment;
import com.dahua.messagesyncsh.pojo.T485;
import com.dahua.messagesyncsh.service.EquipmentService;
import com.dahua.messagesyncsh.service.ProcessorService;
import com.dahua.messagesyncsh.service.enums.EquipmentSType;
import com.smec.zhdt.openapi.client.common.util.DecryptUtils;
import com.smec.zhdt.openapi.client.common.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author smec
 * @date 2022/12/27/13:44
 * Desc:
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PushAgentServiceImpl implements PushAgentService {

    @Value("${mitsubishi.callAppKey:rK5HUbFgsRjuD03x39za0zD3jY5KT0Nm}")
    private String callAppKey;

    @Value("${mitsubishi.callAppSecretKey:boDXcROSQ7Yf2R0mx6l7rikOWAEOFgSAsca2KbT9Xvy}")
    private String callAppSecretKey;

    @Value("${mitsubishi.callAppId:ZHDT20250526_6fc4e9ead4b942889382e3dab7b775d3}")
    private String corpId;


    @Resource
    private EquipmentService equipmentService;

    @Resource
    private ProcessorService processorService;

    /**
     * Desc: 推送信息`
     *
     * @param eventType
     * @param encryptedDto
     * @return {@link PushResponseVo}
     * @author smec
     * @date 2023/1/3 13:57
     */
    @Override
    public PushResponseVo handlePushInfo(String eventType, String corpId, DecryptDto encryptedDto) {

        try {

            DecryptUtils decryptUtils = new DecryptUtils(callAppKey,
                    callAppSecretKey,
                    corpId);

            if (EventTypeEnum.REALTIME_FAULT_DATA.toString().equals(eventType)) {
                // 故障推送
                RtFault eleFaultObject = decryptUtils.getRtFaultObject(encryptedDto.getMsgSignature(),
                        encryptedDto.getTimeStamp(),
                        encryptedDto.getNonce(),
                        encryptedDto.getEncryptMsg());

                log.info("故障推送数据：{}", GsonUtils.toJsonStr(eleFaultObject));

            } else if (EventTypeEnum.MAINTAIN_WORKORDER_DATA.toString().equals(eventType)) {
                //维保工单
                MaintainWorkorder maintainWorkorderObject = decryptUtils.getMaintainWorkorderObject(encryptedDto.getMsgSignature(),
                        encryptedDto.getTimeStamp(),
                        encryptedDto.getNonce(),
                        encryptedDto.getEncryptMsg());

                log.info("维保工单数据：{}", GsonUtils.toJsonStr(maintainWorkorderObject));

            } else if (EventTypeEnum.REALTIME_DATA.toString().equals(eventType)) {
                // 实时数据
                RtData rtDataObject = decryptUtils.getRtDataObject(encryptedDto.getMsgSignature(),
                        encryptedDto.getTimeStamp(),
                        encryptedDto.getNonce(),
                        encryptedDto.getEncryptMsg());

                /*  转成control56发送到consumer消费*/
                T485 t485 = null;

                List<Equipment> equipment = equipmentService.detail(EquipmentQueryCriteria.builder().bk1(rtDataObject.getEleContractNo()).build(), EquipmentSType.BK1);
                if (equipment.size() != 1) {
                    log.info("【Mitsubishi】: {}设备不存在或不唯一", rtDataObject.getEleContractNo());
                } else {
                    try{
                        t485 = this.convert(rtDataObject, equipment.get(0));
                    }catch (Exception e){
                        log.error("【Mitsubishi】: {}", e.getMessage());
                    }
                }

                if (t485 != null) {
                    boolean allZero = true;
                    for (Integer[] data : t485.getData()){
                        if (data[1] != 0) {
                            allZero = false;
                            break;
                        }
                    }
                    if (allZero) {
                        log.error("【Mitsubishi】：数据全为0 {}", t485);
                    }else{
                        processorService.handleT485(Collections.singletonList(t485));
                    }
                }else{
                    log.error("【Mitsubishi】：数据存在必要缺失 \n{}", rtDataObject);
                }

            } else if (EventTypeEnum.FAST_REPAIR_WORKORDER_DATA.toString().equals(eventType)) {
                // 急修数据
                FastRepairWorkorder fastRepairWorkorderObject = decryptUtils.getFastRepairWorkorderObject(encryptedDto.getMsgSignature(),
                        encryptedDto.getTimeStamp(),
                        encryptedDto.getNonce(),
                        encryptedDto.getEncryptMsg());

                log.info("急修数据：{}", GsonUtils.toJsonStr(fastRepairWorkorderObject));

            } else if (EventTypeEnum.RUN_STATISTICS_DATA.toString().equals(eventType)) {
                // 运行统计数据
                RunStatistics runStatisticsObject = decryptUtils.getRunStatisticsObject(encryptedDto.getMsgSignature(),
                        encryptedDto.getTimeStamp(),
                        encryptedDto.getNonce(),
                        encryptedDto.getEncryptMsg());

                log.info("运行统计数据：{}", GsonUtils.toJsonStr(runStatisticsObject));
            }
        } catch (Exception e) {
            //异常处理
            log.error(e.getMessage());
            return PushResponseVo.builder().code("5000")
                    .message("fail:" + e.getMessage())
                    .timeStamp(encryptedDto.getTimeStamp())
                    .nonce(encryptedDto.getNonce())
                    .build();
        }


        //消费成功请返回如下对象
        return PushResponseVo.builder()
                .code("2000")
                .message("success")
                .timeStamp(encryptedDto.getTimeStamp())
                .nonce(encryptedDto.getNonce())
                .build();
    }


    public T485 convert(RtData rtData, Equipment equipment) throws RuntimeException{
        T485 t485 = T485.builder()
                .equipmentId(equipment.getRegisterNumber())
                .build();
        try {
            // 解析带时区的时间
            // 修复时区格式：+8:00 → +08:00
            String fixedIsoTime = rtData.getDateStr().replace("+8:00", "+08:00");

            OffsetDateTime odt = OffsetDateTime.parse(fixedIsoTime);

            // 转换为 Instant（UTC 时间）
            Instant instant = odt.toInstant();

            // 获取毫秒级时间戳
            long timestampMillis = instant.toEpochMilli();

            t485.setDataTime(timestampMillis);
        } catch (Exception e) {
            throw new RuntimeException("时间解析错误");
        }

        t485.setManufacturer("mitsubishi");

        if (rtData.getLifterFlag() == null){
            throw new RuntimeException("lifterFlag为空");
        }

        if (rtData.getData() != null) {
            if (rtData.getLifterFlag().equals("电梯")) {
                this.handleLift(rtData.getData(), t485);
            } else {
                this.handleEscalator(rtData.getData(), t485);
            }
        } else {
            throw new RuntimeException("data为空");
        }
        return t485;
    }


    public void handleLift(RtData.RealtimeSendData data, T485 t485) {
        int code1 = 0;
        int code2 = 0;
        if (data.getdEleRunMode() != null) {
            switch (data.getdEleRunMode().trim()) {
                case "离线": {
                    code1++;
                    break;
                }
                case "正常": {
                    code1 += 2;
                    break;
                }
                case "锁梯": {
                    code1 += 4;
                    break;
                }
                case "故障": {
                    code1 += 8;
                    break;
                }
                case "检修": {
                    code1 += 16;
                    break;
                }
                case "特殊": {
                    code1 += 32;
                    break;
                }
                case "维保": {
                    code1 += 64;
                    break;
                }
                case "困人故障": {
                    code1 += 128;
                    break;
                }
                case "不能使用故障": {
                    code1 += 256;
                    break;
                }
                case "不能再启用故障": {
                    code1 += 512;
                    break;
                }
                default: {
                    code1 += 1024;
                    break;
                }
            }
        }
        if (data.getdRtEleRunStatus() != null) {
            switch (data.getdRtEleRunStatus().trim()) {
                case "停止": {
                    code1 += 4096;
                    break;
                }
                case "下行": {
                    code1 += 8192;
                    break;
                }
                case "上行": {
                    code1 += 16384;
                    break;
                }
                default: {
                    code1 += 2048;
                    break;
                }
            }
        }

        if (data.getdRtDoorState() != null) {
            switch (data.getdRtDoorState().trim()) {
                case "全开": {
                    code2++;
                    break;
                }
                case "全关": {
                    code2 += 2;
                    break;
                }
                case "非全关": {
                    code2 += 4;
                    break;
                }
                case "开门中": {
                    code2 += 8;
                    break;
                }
                case "关门中": {
                    code2 += 16;
                    break;
                }
                default: {
                    code2 += 32;
                    break;
                }
            }
        }

        List<Integer[]> list = new ArrayList<>();
        list.add(new Integer[]{40001, code1});
        list.add(new Integer[]{40002, code2});
        t485.setData(list);
    }

    public void handleEscalator(RtData.RealtimeSendData data, T485 t485) {
        log.info("Receive mitsubishi's escalator {} info {}", t485.getEquipmentId(), data.toString());
        int code1 = 0;
        int code2 = 0;
        if (data.getdEleRunMode() != null) {
            switch (data.getdEleRunMode().trim()) {
                case "离线": {
                    code1++;
                    break;
                }
                case "运行": {
                    code1 += 2;
                    break;
                }
                case "停止": {
                    code1 += 4;
                    break;
                }
                case "故障": {
                    code1 += 8;
                    break;
                }
                case "检修": {
                    code1 += 16;
                    break;
                }
                case "特殊": {
                    code1 += 32;
                    break;
                }
                default: {
                    code1 += 64;
                    break;
                }
            }
        }

        if (data.getRtEscRunDir() != null) {
            switch (data.getRtEscRunDir().trim()) {
                case "停止": {
                    code2++;
                    break;
                }
                case "下行": {
                    code2 += 2;
                    break;
                }
                case "上行": {
                    code2 += 4;
                    break;
                }
                default: {
                    code2 += 8;
                    break;
                }
            }
        }

        if (data.getdRtEleRunStatus() != null) {
            switch (data.getdRtEleRunStatus().trim().substring(0, 2)) {
                case "高速": {
                    code2 += 16;
                    break;
                }
                case "低速": {
                    code2 += 32;
                    break;
                }
                case "零速": {
                    code2 += 64;
                    break;
                }
            }
        }

        List<Integer[]> list = new ArrayList<>();
        list.add(new Integer[]{40001, code1});
        list.add(new Integer[]{40002, code2});
        t485.setData(list);
        log.info("Convert mitsubishi's escalator {} info to {}", t485.getEquipmentId(), t485.toString());
    }

}
